@@ -4,16 +4,26 @@ from __future__ import division |
||
4 | 4 |
|
5 | 5 |
import random |
6 | 6 |
|
7 |
+from django.conf import settings |
|
8 |
+from django.db import transaction |
|
7 | 9 |
from django_logit import logit |
8 | 10 |
from django_response import response |
11 |
+from pywe_marketcode import tickettocode |
|
12 |
+from pywe_storage import RedisStorage |
|
9 | 13 |
|
14 |
+from account.models import UserInfo |
|
10 | 15 |
from logs.models import MchInfoDecryptLogInfo, MchInfoEncryptLogInfo |
16 |
+from marketcode.models import MarketCodeInfo |
|
11 | 17 |
from mch.models import ActivityInfo, BrandInfo, ModelInfo |
12 | 18 |
from utils.algorithm.b64 import b64_decrypt, b64_encrypt |
13 | 19 |
from utils.algorithm.caesar import caesar_decrypt, caesar_encrypt |
14 | 20 |
from utils.algorithm.rsalg import rsa_decrypt, rsa_encrypt |
21 |
+from utils.error.errno_utils import MarketCodeStatusCode, UserStatusCode |
|
22 |
+from utils.redis.connect import r |
|
15 | 23 |
|
16 | 24 |
|
25 |
+WECHAT = settings.WECHAT |
|
26 |
+ |
|
17 | 27 |
# CIPHER_ALGORITHM = ('CAESAR', 'B64', 'RSA') |
18 | 28 |
CIPHER_ALGORITHM = ('CAESAR', ) |
19 | 29 |
|
@@ -35,6 +45,30 @@ def encrypt(request): |
||
35 | 45 |
|
36 | 46 |
mieli, created_at = MchInfoEncryptLogInfo.objects.get_or_create(plaintext=plaintext) |
37 | 47 |
|
48 |
+ if settings.KODO_MARKET_CODE_ENABLED: |
|
49 |
+ if created_at or not mieli.code: |
|
50 |
+ with transaction.atomic(): |
|
51 |
+ marketcode = MarketCodeInfo.objects.select_for_update().filter(has_used=False).first() |
|
52 |
+ |
|
53 |
+ if not marketcode: |
|
54 |
+ return response(MarketCodeStatusCode.MARKET_CODE_NOT_FOUND) |
|
55 |
+ |
|
56 |
+ marketcode.has_used = True |
|
57 |
+ marketcode.save() |
|
58 |
+ |
|
59 |
+ mieli.code = marketcode.code |
|
60 |
+ mieli.code_url = marketcode.code_url |
|
61 |
+ mieli.brand_pk = brand_pk |
|
62 |
+ mieli.model_pk = model_pk |
|
63 |
+ mieli.distributor_pk = distributor_pk |
|
64 |
+ mieli.sn = sn |
|
65 |
+ mieli.operator_id = optor_id |
|
66 |
+ mieli.save() |
|
67 |
+ |
|
68 |
+ return response(200, data={ |
|
69 |
+ 'ciphertext': mieli.code_url, |
|
70 |
+ }) |
|
71 |
+ |
|
38 | 72 |
if created_at: |
39 | 73 |
alg = random.choice(CIPHER_ALGORITHM) |
40 | 74 |
|
@@ -160,3 +194,83 @@ def decrypt(request): |
||
160 | 194 |
'redpack_info': elog.redpack_info if elog else {}, |
161 | 195 |
'integral': model.integral, |
162 | 196 |
}) |
197 |
+ |
|
198 |
+ |
|
199 |
+@logit(res=True) |
|
200 |
+def decrypt2(request): |
|
201 |
+ code_ticket = request.POST.get('code_ticket', '') |
|
202 |
+ user_id = request.POST.get('user_id', '') |
|
203 |
+ |
|
204 |
+ try: |
|
205 |
+ user = UserInfo.objects.get(user_id=user_id) |
|
206 |
+ except UserInfo.DoesNotExist: |
|
207 |
+ return response(UserStatusCode.USER_NOT_FOUND) |
|
208 |
+ |
|
209 |
+ wxcfg = WECHAT.get('JSAPI', {}) |
|
210 |
+ |
|
211 |
+ appid = wxcfg.get('appID') |
|
212 |
+ secret = wxcfg.get('appsecret') |
|
213 |
+ |
|
214 |
+ code_info = tickettocode(code_ticket=code_ticket, openid=user.openid_miniapp, appid=appid, secret=secret, token=None, storage=RedisStorage(r)) |
|
215 |
+ |
|
216 |
+ code = code_info.get('code', '') |
|
217 |
+ |
|
218 |
+ try: |
|
219 |
+ miel = MchInfoEncryptLogInfo.objects.get(code=code) |
|
220 |
+ except MchInfoEncryptLogInfo.DoesNotExist: |
|
221 |
+ return response() |
|
222 |
+ |
|
223 |
+ plaintext = miel.plaintext |
|
224 |
+ |
|
225 |
+ # brand_id#model_id#distributor_id#sn#time |
|
226 |
+ # AAAA#AAAAAA#AAAAA#AAAAAAAAAAAAAA#180224 |
|
227 |
+ brand_pk, model_pk, distributor_pk, sn, time = plaintext.split('#') |
|
228 |
+ |
|
229 |
+ try: |
|
230 |
+ brand = BrandInfo.objects.get(pk=brand_pk) |
|
231 |
+ except BrandInfo.DoesNotExist: |
|
232 |
+ brand = None |
|
233 |
+ |
|
234 |
+ try: |
|
235 |
+ model = ModelInfo.objects.get(pk=model_pk) |
|
236 |
+ except ModelInfo.DoesNotExist: |
|
237 |
+ model = None |
|
238 |
+ |
|
239 |
+ mdli, created_at = MchInfoDecryptLogInfo.objects.get_or_create(ciphertext=ciphertext, defaults={ |
|
240 |
+ 'brand_pk': brand_pk, |
|
241 |
+ 'model_pk': model_pk, |
|
242 |
+ 'distributor_pk': distributor_pk, |
|
243 |
+ 'sn': sn, |
|
244 |
+ 'decrypt_count': 1, |
|
245 |
+ }) |
|
246 |
+ |
|
247 |
+ if not created_at: |
|
248 |
+ mdli.decrypt_count += 1 |
|
249 |
+ mdli.save() |
|
250 |
+ |
|
251 |
+ act = ActivityInfo.objects.filter(status=True).order_by('-pk').first() |
|
252 |
+ has_unexpired_activity = True if act and act.has_unexpired_activity(model.model_uni_name) else False |
|
253 |
+ |
|
254 |
+ coupon_info = { |
|
255 |
+ 'coupon_expire_at': act.final_coupon_expire_at(created_at=None), |
|
256 |
+ 'coupon_value': act.coupon_value, |
|
257 |
+ } if has_unexpired_activity else { |
|
258 |
+ 'coupon_expire_at': '', |
|
259 |
+ 'coupon_value': 0, |
|
260 |
+ } |
|
261 |
+ |
|
262 |
+ return response(200, data={ |
|
263 |
+ 'plaintext': plaintext, |
|
264 |
+ 'logo_url': brand.brand_logo_url if brand else '', |
|
265 |
+ 'model_imgs': model.images if model else [], |
|
266 |
+ 'goodsInfo': { |
|
267 |
+ 'BrandID': brand_pk, |
|
268 |
+ 'Brand': brand.brand_name if brand else '', |
|
269 |
+ 'ModelID': model_pk, |
|
270 |
+ 'Model': (model.model_full_name or model.model_name) if model else '', |
|
271 |
+ 'DistributorID': distributor_pk, |
|
272 |
+ 'SerialNo': sn, |
|
273 |
+ }, |
|
274 |
+ 'has_unexpired_activity': has_unexpired_activity, |
|
275 |
+ 'coupon_info': coupon_info, |
|
276 |
+ }) |
@@ -214,6 +214,7 @@ urlpatterns += [ |
||
214 | 214 |
urlpatterns += [ |
215 | 215 |
url(r'^encrypt$', encrypt_views.encrypt, name='encrypt'), |
216 | 216 |
url(r'^decrypt$', encrypt_views.decrypt, name='decrypt'), |
217 |
+ url(r'^decrypt2$', encrypt_views.decrypt2, name='decrypt2'), |
|
217 | 218 |
] |
218 | 219 |
|
219 | 220 |
urlpatterns += [ |
@@ -57,6 +57,7 @@ INSTALLED_APPS = ( |
||
57 | 57 |
'guideline', |
58 | 58 |
'integral', |
59 | 59 |
'logs', |
60 |
+ 'marketcode', |
|
60 | 61 |
'mch', |
61 | 62 |
'message', |
62 | 63 |
'miniapp', |
@@ -252,12 +253,12 @@ QINIU = { |
||
252 | 253 |
'secret_key': '05sCekniLCgM6-d_PxrH8sFjvEOsx3ev-FgS7R-k', |
253 | 254 |
'bucket_default': 'photo', |
254 | 255 |
'buckets': { |
255 |
- 'original': 'http://orf3sfb8s.bkt.clouddn.com', |
|
256 |
- 'photo': 'http://orf3lnlmb.bkt.clouddn.com', |
|
257 |
- 'prettify': 'http://orzfu8zxw.bkt.clouddn.com', |
|
258 |
- 'thumbnail': 'http://orf3ahvt6.bkt.clouddn.com', |
|
259 |
- 'thumbnail2': 'http://orf3muf5n.bkt.clouddn.com', |
|
260 |
- 'watermark': 'http://orf3qne9f.bkt.clouddn.com', |
|
256 |
+ 'original': 'http://original.img.pai.ai', |
|
257 |
+ 'photo': 'http://photo.img.pai.ai', |
|
258 |
+ 'prettify': 'http://prettify.img.pai.ai', |
|
259 |
+ 'thumbnail': 'http://thumbnail.img.pai.ai', |
|
260 |
+ 'thumbnail2': 'http://thumbnail2.img.pai.ai', |
|
261 |
+ 'watermark': 'http://watermark.img.pai.ai', |
|
261 | 262 |
} |
262 | 263 |
} |
263 | 264 |
|
@@ -419,6 +420,16 @@ PHONE_2_ADMINISTRATIVE_DIVISION = 'https://www.baifubao.com/callback?cmd=1059&ca |
||
419 | 420 |
|
420 | 421 |
TESTING_SNS = ['000000'] |
421 | 422 |
|
423 |
+COMPONENT_CALLBACK_CONFIG = { |
|
424 |
+ 'tousername': 'brand_id', |
|
425 |
+} |
|
426 |
+ |
|
427 |
+# 测试文件 |
|
428 |
+TESTING_ZBAR = os.path.join(BASE_DIR, 'utils/zbar/zbar.jpg').replace('\\', '/') |
|
429 |
+ |
|
430 |
+# 一物一码设置 |
|
431 |
+KODO_MARKET_CODE_ENABLED = False |
|
432 |
+ |
|
422 | 433 |
# 开发调试相关配置 |
423 | 434 |
if DEBUG: |
424 | 435 |
try: |
@@ -7,7 +7,7 @@ from logs.models import MchInfoDecryptLogInfo, MchInfoEncryptLogInfo, MchLogInfo |
||
7 | 7 |
|
8 | 8 |
|
9 | 9 |
class MchInfoEncryptLogInfoAdmin(Readonly2ModelAdmin, admin.ModelAdmin): |
10 |
- list_display = ('plaintext', 'alg', 'ciphertext', 'brand_pk', 'model_pk', 'distributor_pk', 'sn', 'operator_id', 'is_send_redpack', 'redpack_amount', 'redpack_max_amount', 'has_send_redpack', 'redpack_send_amount', 'user_id', 'nickname', 'is_clerk_send_redpack', 'clerk_redpack_amount', 'clerk_redpack_max_amount', 'has_clerk_send_redpack', 'clerk_redpack_send_amount', 'clerk_user_id', 'clerk_nickname', 'status', 'created_at', 'updated_at') |
|
10 |
+ list_display = ('plaintext', 'alg', 'ciphertext', 'brand_pk', 'model_pk', 'distributor_pk', 'sn', 'code', 'code_url', 'operator_id', 'is_send_redpack', 'redpack_amount', 'redpack_max_amount', 'has_send_redpack', 'redpack_send_amount', 'user_id', 'nickname', 'is_clerk_send_redpack', 'clerk_redpack_amount', 'clerk_redpack_max_amount', 'has_clerk_send_redpack', 'clerk_redpack_send_amount', 'clerk_user_id', 'clerk_nickname', 'status', 'created_at', 'updated_at') |
|
11 | 11 |
list_filter = ('alg', 'brand_pk', 'model_pk', 'distributor_pk', 'operator_id', 'is_send_redpack', 'has_send_redpack', 'is_clerk_send_redpack', 'has_clerk_send_redpack', 'status') |
12 | 12 |
readonly_fields_exclude = ('is_send_redpack', 'redpack_amount', 'redpack_max_amount', 'is_clerk_send_redpack', 'clerk_redpack_amount', 'clerk_redpack_max_amount') |
13 | 13 |
|
@@ -0,0 +1,25 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+# Generated by Django 1.11.28 on 2020-03-22 21:25 |
|
3 |
+from __future__ import unicode_literals |
|
4 |
+ |
|
5 |
+from django.db import migrations, models |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ dependencies = [ |
|
11 |
+ ('logs', '0013_mchinfoencryptloginfo_user_ids'), |
|
12 |
+ ] |
|
13 |
+ |
|
14 |
+ operations = [ |
|
15 |
+ migrations.AddField( |
|
16 |
+ model_name='mchinfoencryptloginfo', |
|
17 |
+ name='code', |
|
18 |
+ field=models.CharField(blank=True, db_index=True, help_text='\u4e5d\u4f4d\u7684\u5b57\u7b26\u4e32\u539f\u59cb\u7801', max_length=16, null=True, verbose_name='code'), |
|
19 |
+ ), |
|
20 |
+ migrations.AddField( |
|
21 |
+ model_name='mchinfoencryptloginfo', |
|
22 |
+ name='code_url', |
|
23 |
+ field=models.CharField(blank=True, db_index=True, help_text='28\u4f4d\u666e\u901a\u7801\u5b57\u7b26\t', max_length=128, null=True, verbose_name='code_url'), |
|
24 |
+ ), |
|
25 |
+ ] |
@@ -18,6 +18,10 @@ class MchInfoEncryptLogInfo(BaseModelMixin): |
||
18 | 18 |
|
19 | 19 |
sn = models.CharField(_(u'sn'), max_length=32, blank=True, null=True, help_text=u'序列号', db_index=True) |
20 | 20 |
|
21 |
+ # 一物一码 |
|
22 |
+ code = models.CharField(_(u'code'), max_length=16, blank=True, null=True, help_text=u'九位的字符串原始码', db_index=True) |
|
23 |
+ code_url = models.CharField(_(u'code_url'), max_length=128, blank=True, null=True, help_text=u'28位普通码字符 ', db_index=True) |
|
24 |
+ |
|
21 | 25 |
operator_id = models.CharField(_(u'operator_id'), max_length=32, blank=True, null=True, help_text=u'操作员唯一标识', db_index=True) |
22 | 26 |
|
23 | 27 |
is_send_redpack = models.BooleanField(_(u'is_send_redpack'), default=False, help_text=u'是否发放红包', db_index=True) |
@@ -0,0 +1,12 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.contrib import admin |
|
4 |
+ |
|
5 |
+from marketcode.models import MarketCodeInfo |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class MarketCodeInfoAdmin(admin.ModelAdmin): |
|
9 |
+ list_display = ('isv_application_id', 'application_id', 'code', 'code_url', 'has_used', 'status', 'created_at', 'updated_at') |
|
10 |
+ |
|
11 |
+ |
|
12 |
+admin.site.register(MarketCodeInfo, MarketCodeInfoAdmin) |
@@ -0,0 +1,8 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.apps import AppConfig |
|
5 |
+ |
|
6 |
+ |
|
7 |
+class MarketcodeConfig(AppConfig): |
|
8 |
+ name = 'marketcode' |
@@ -0,0 +1,34 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+# Generated by Django 1.11.26 on 2020-01-13 10:32 |
|
3 |
+from __future__ import unicode_literals |
|
4 |
+ |
|
5 |
+from django.db import migrations, models |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ initial = True |
|
11 |
+ |
|
12 |
+ dependencies = [ |
|
13 |
+ ] |
|
14 |
+ |
|
15 |
+ operations = [ |
|
16 |
+ migrations.CreateModel( |
|
17 |
+ name='MarketCodeInfo', |
|
18 |
+ fields=[ |
|
19 |
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|
20 |
+ ('status', models.BooleanField(db_index=True, default=True, help_text='Status', verbose_name='status')), |
|
21 |
+ ('created_at', models.DateTimeField(auto_now_add=True, help_text='Create Time', verbose_name='created_at')), |
|
22 |
+ ('updated_at', models.DateTimeField(auto_now=True, help_text='Update Time', verbose_name='updated_at')), |
|
23 |
+ ('isv_application_id', models.CharField(blank=True, db_index=True, help_text='\u5916\u90e8\u5355\u53f7', max_length=128, null=True, verbose_name='isv_application_id')), |
|
24 |
+ ('application_id', models.IntegerField(db_index=True, default=0, help_text='\u7533\u8bf7\u5355\u53f7', verbose_name='application_id')), |
|
25 |
+ ('code', models.CharField(blank=True, db_index=True, help_text='\u4e5d\u4f4d\u7684\u5b57\u7b26\u4e32\u539f\u59cb\u7801', max_length=16, null=True, verbose_name='code')), |
|
26 |
+ ('code_url', models.CharField(blank=True, db_index=True, help_text='28\u4f4d\u666e\u901a\u7801\u5b57\u7b26\t', max_length=128, null=True, verbose_name='code_url')), |
|
27 |
+ ('has_used', models.BooleanField(db_index=True, default=True, help_text='\u662f\u5426\u5df2\u4f7f\u7528', verbose_name='has_used')), |
|
28 |
+ ], |
|
29 |
+ options={ |
|
30 |
+ 'verbose_name': '\u4e00\u7269\u4e00\u7801\u4fe1\u606f', |
|
31 |
+ 'verbose_name_plural': '\u4e00\u7269\u4e00\u7801\u4fe1\u606f', |
|
32 |
+ }, |
|
33 |
+ ), |
|
34 |
+ ] |
@@ -0,0 +1,20 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+# Generated by Django 1.11.26 on 2020-01-13 10:51 |
|
3 |
+from __future__ import unicode_literals |
|
4 |
+ |
|
5 |
+from django.db import migrations, models |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ dependencies = [ |
|
11 |
+ ('marketcode', '0001_initial'), |
|
12 |
+ ] |
|
13 |
+ |
|
14 |
+ operations = [ |
|
15 |
+ migrations.AlterField( |
|
16 |
+ model_name='marketcodeinfo', |
|
17 |
+ name='has_used', |
|
18 |
+ field=models.BooleanField(db_index=True, default=False, help_text='\u662f\u5426\u5df2\u4f7f\u7528', verbose_name='has_used'), |
|
19 |
+ ), |
|
20 |
+ ] |
@@ -0,0 +1,25 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+# Generated by Django 1.11.26 on 2020-01-13 18:20 |
|
3 |
+from __future__ import unicode_literals |
|
4 |
+ |
|
5 |
+from django.db import migrations, models |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class Migration(migrations.Migration): |
|
9 |
+ |
|
10 |
+ dependencies = [ |
|
11 |
+ ('marketcode', '0002_auto_20200113_1851'), |
|
12 |
+ ] |
|
13 |
+ |
|
14 |
+ operations = [ |
|
15 |
+ migrations.AddField( |
|
16 |
+ model_name='marketcodeinfo', |
|
17 |
+ name='code_index', |
|
18 |
+ field=models.IntegerField(default=0, help_text='\u8be5\u7801\u5728\u6279\u6b21\u4e2d\u7684\u504f\u79fb\u91cf\t', verbose_name='code_index'), |
|
19 |
+ ), |
|
20 |
+ migrations.AddField( |
|
21 |
+ model_name='marketcodeinfo', |
|
22 |
+ name='lattice', |
|
23 |
+ field=models.CharField(blank=True, help_text='361 \u5b57\u8282\u7684 01 \u70b9\u9635\uff0c\u7528\u4e8e\u652f\u6301\u751f\u6210 19 * 19 \u7684\u5fae\u578b\u7801\uff0c0 \u4e3a\u767d\uff0c1 \u4e3a\u9ed1', max_length=361, null=True, verbose_name='code'), |
|
24 |
+ ), |
|
25 |
+ ] |
@@ -0,0 +1,24 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.db import models |
|
4 |
+from django.utils.translation import ugettext_lazy as _ |
|
5 |
+from django_models_ext import BaseModelMixin |
|
6 |
+ |
|
7 |
+ |
|
8 |
+class MarketCodeInfo(BaseModelMixin): |
|
9 |
+ isv_application_id = models.CharField(_(u'isv_application_id'), max_length=128, blank=True, null=True, help_text=u'外部单号', db_index=True) |
|
10 |
+ application_id = models.IntegerField(_(u'application_id'), default=0, help_text=u'申请单号', db_index=True) |
|
11 |
+ |
|
12 |
+ lattice = models.CharField(_(u'code'), max_length=361, blank=True, null=True, help_text=u'361 字节的 01 点阵,用于支持生成 19 * 19 的微型码,0 为白,1 为黑') |
|
13 |
+ code = models.CharField(_(u'code'), max_length=16, blank=True, null=True, help_text=u'九位的字符串原始码', db_index=True) |
|
14 |
+ code_index = models.IntegerField(_(u'code_index'), default=0, help_text=u'该码在批次中的偏移量 ') |
|
15 |
+ code_url = models.CharField(_(u'code_url'), max_length=128, blank=True, null=True, help_text=u'28位普通码字符 ', db_index=True) |
|
16 |
+ |
|
17 |
+ has_used = models.BooleanField(_(u'has_used'), default=False, help_text=_(u'是否已使用'), db_index=True) |
|
18 |
+ |
|
19 |
+ class Meta: |
|
20 |
+ verbose_name = _(u'一物一码信息') |
|
21 |
+ verbose_name_plural = _(u'一物一码信息') |
|
22 |
+ |
|
23 |
+ def __unicode__(self): |
|
24 |
+ return unicode(self.pk) |
@@ -0,0 +1,6 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.test import TestCase |
|
5 |
+ |
|
6 |
+# Create your tests here. |
@@ -0,0 +1,6 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+from __future__ import unicode_literals |
|
3 |
+ |
|
4 |
+from django.shortcuts import render |
|
5 |
+ |
|
6 |
+# Create your views here. |
@@ -0,0 +1,41 @@ |
||
1 |
+# -*- coding: utf-8 -*- |
|
2 |
+ |
|
3 |
+from django.conf import settings |
|
4 |
+from pywe_marketcode import applycodedownload |
|
5 |
+from pywe_storage import RedisStorage |
|
6 |
+ |
|
7 |
+from marketcode.models import MarketCodeInfo |
|
8 |
+from utils.redis.connect import r |
|
9 |
+ |
|
10 |
+ |
|
11 |
+WECHAT = settings.WECHAT |
|
12 |
+ |
|
13 |
+ |
|
14 |
+def marketcodedownload(application_id, code_start, code_end, isv_application_id=''): |
|
15 |
+ wxcfg = WECHAT.get('JSAPI', {}) |
|
16 |
+ |
|
17 |
+ appid = wxcfg.get('appID') |
|
18 |
+ secret = wxcfg.get('appsecret') |
|
19 |
+ |
|
20 |
+ codes = applycodedownload(application_id=application_id, code_start=code_start, code_end=code_end, appid=appid, secret=secret, token=None, storage=RedisStorage(r)) |
|
21 |
+ |
|
22 |
+ lattice, code, code_index, code_url = '' |
|
23 |
+ for idx, item in enumerate(codes): |
|
24 |
+ if idx % 4 == 0: |
|
25 |
+ lattice = item |
|
26 |
+ if idx % 4 == 1: |
|
27 |
+ code = item |
|
28 |
+ if idx % 4 == 2: |
|
29 |
+ code_index = item |
|
30 |
+ if idx % 4 == 3: |
|
31 |
+ code_url = item |
|
32 |
+ MarketCodeInfo.objects.create( |
|
33 |
+ isv_application_id=isv_application_id, |
|
34 |
+ application_id=application_id, |
|
35 |
+ lattice=lattice, |
|
36 |
+ code=code, |
|
37 |
+ code_index=code_index, |
|
38 |
+ code_url=code_url |
|
39 |
+ ) |
|
40 |
+ |
|
41 |
+ |
@@ -2,6 +2,7 @@ pywe-card==1.0.0 |
||
2 | 2 |
pywe-component==1.0.1 |
3 | 3 |
pywe-component-preauthcode==1.0.3 |
4 | 4 |
pywe-jssdk==1.1.0 |
5 |
+pywe-marketcode==1.0.1 |
|
5 | 6 |
pywe-membercard==1.0.3 |
6 | 7 |
pywe-miniapp==1.1.5 |
7 | 8 |
pywe-oauth==1.0.7 |
@@ -59,6 +59,39 @@ class ProductStatusCode(BaseStatusCode): |
||
59 | 59 |
PRODUCT_NOT_USED = StatusCodeField(502012, 'Product Not Used', description=u'产品未使用') |
60 | 60 |
|
61 | 61 |
|
62 |
+class MemberGoodStatusCode(BaseStatusCode): |
|
63 |
+ """ 会员商品相关错误码 5035xx """ |
|
64 |
+ GOOD_NOT_FOUND = StatusCodeField(503501, 'Good Not Found', description=u'商品不存在') |
|
65 |
+ |
|
66 |
+ GOOD_NO_EXCHANGE_PERMISSION = StatusCodeField(503502, 'Good No Exchange Permission', description=u'商品无兑换权限') |
|
67 |
+ GOOD_INTEGRAL_NOT_ENOUGH = StatusCodeField(503503, 'Good Integral Not Enough', description=u'商品兑换积分不足') |
|
68 |
+ GOOD_STOCK_NOT_ENOUGH = StatusCodeField(503504, 'Good Integral Not Enough', description=u'商品库存不足') |
|
69 |
+ |
|
70 |
+ |
|
71 |
+class MemberRightStatusCode(BaseStatusCode): |
|
72 |
+ """ 会员商品相关错误码 5036xx """ |
|
73 |
+ RIGHT_NOT_FOUND = StatusCodeField(503601, 'Right Not Found', description=u'权益不存在') |
|
74 |
+ |
|
75 |
+ |
|
76 |
+class MemberActivityStatusCode(BaseStatusCode): |
|
77 |
+ """ 会员活动相关错误码 5037xx """ |
|
78 |
+ ACTIVITY_NOT_FOUND = StatusCodeField(503701, 'Activity Not Found', description=u'活动不存在') |
|
79 |
+ |
|
80 |
+ |
|
81 |
+class MemberCouponStatusCode(BaseStatusCode): |
|
82 |
+ """ 会员优惠券相关错误码 5040xx """ |
|
83 |
+ USER_COUPON_NOT_FOUND = StatusCodeField(504001, 'User Coupon Not Found', description=u'用户优惠券不存在') |
|
84 |
+ |
|
85 |
+ USER_COUPON_HAS_USED = StatusCodeField(504010, 'User Coupon Has Used', description=u'用户优惠券已使用') |
|
86 |
+ USER_COUPON_NOT_ACTIVED = StatusCodeField(504011, 'User Coupon Not Actived', description=u'用户优惠券未生效') |
|
87 |
+ USER_COUPON_HAS_EXPIRED = StatusCodeField(504012, 'User Coupon Has Expired', description=u'用户优惠券已过期') |
|
88 |
+ |
|
89 |
+ |
|
90 |
+class MarketCodeStatusCode(BaseStatusCode): |
|
91 |
+ """ 一物一码相关错误码 5050xx """ |
|
92 |
+ MARKET_CODE_NOT_FOUND = StatusCodeField(505001, 'Market Code Not Found', description=u'一物一码不存在') |
|
93 |
+ |
|
94 |
+ |
|
62 | 95 |
class LensmanStatusCode(BaseStatusCode): |
63 | 96 |
""" 摄影师相关错误码 4000xx """ |
64 | 97 |
LENSMAN_NOT_FOUND = StatusCodeField(400001, 'Lensman Not Found', description=u'摄影师不存在') |